'use strict';
// node.js 文件操作对象
// const fs = require('fs');
const path = require('path');
// 数据加密
const crypto = require('crypto');
const COS = require('cos-nodejs-sdk-v5');
const {
  COS: { SecretId, SecretKey, Protocol },
} = require('../../../project.config');

const cos = new COS({
  SecretId,
  SecretKey,
  Protocol, // 请求协议： 'https:' 或 'http:'
});

// 故名思意 异步二进制 写入流
// const awaitWriteStream = require('await-stream-ready').write;
// // 管道读入一个虫洞。
const sendToWormhole = require('stream-wormhole');
// const Pump = require('mz-modules/pump');
const Controller = require('egg').Controller;
class updateController extends Controller {
  /**
     * @api {Post} /api/update 单文件上传
     * @apiGroup 文件上传
     * @apiParam {file} file （必填）
     * @apiParam {INTEGER} type   1商品，2评价, 3轮播图（必填）
     * @apiParamExample 参数模板
     {
      }
     * @apiSuccessExample 成功返回
    {
        "msg": "添加成功",
        "result": {
            "id": 130,
            "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413603112-f121d135f39f03e48da5fe5e8ced5b0a.jpg"
        }
    }
     *
     * @apiErrorExample 错误返回
     * {
     *  "msg":"请选择文件"
     * }
     *
     */
  // 单文件上传
  async index() {
    const { ctx, service } = this;
    try {
      this.md5 = crypto.createHash('md5');
      let stream;

      try {
        stream = await ctx.getFileStream();
      } catch (error) {
        ctx.body = ctx.response.error('请上传文件');
      }
      if (!stream) {
        return;
      }
      // 新建一个文件名
      let userData = ctx.adminInfo || ctx.userInfo;

      /** 生成filename，文件存储目录及格式为 /project_name_用户id/_时间戳_文件名 */
      let filename =
        `/${userData?.project_name || '默认项目'}_${
          userData?.id
        }/_${+new Date()}_` +
        this.md5.update(stream.filename).digest('hex') +
        path.extname(stream.filename).toLocaleLowerCase();
      const cosData = await ctx.helper._upload(filename, stream);

      // 保存到数据库 返回上传的信息
      ctx.body = await service.shop.photo.index(cosData, stream.fields.type);

      // 文件生成绝对路径
      // 当然这里这样是不行的，因为你还要判断一下是否存在文件路径
      // const target = path.join(this.config.baseDir, 'app/public/uploads', filename);
      // // 生成一个文件写入 文件流
      // const writeStream = fs.createWriteStream(target);
      // try {
      //   // 异步把文件流 写入
      //   await awaitWriteStream(stream.pipe(writeStream));
      // } catch (err) {
      //   // 如果出现错误，关闭管道
      //   await sendToWormhole(stream);
      //   throw err;
      // }
      // // 返回上传的信息
      // // ctx.body = ctx.response.success({
      // //   url: '/public/uploads/' + filename,
      // // });
      // // 保存到数据库 返回上传的信息
      // ctx.body = await service.photo.index(path.join('/public/uploads', filename), stream.fields.type);
    } catch (error) {
      console.log(error);
      ctx.body = ctx.response.error(error.message);
    }
  }
  /**
     * @api {Post} /api/updateM 多文件上传
     * @apiGroup 文件上传
     * @apiParam {file} file （必填）
     * @apiParam {INTEGER} type   1商品，2评价, 3轮播图（必填）
     * @apiParamExample 参数模板
     {
      }
     * @apiSuccessExample 成功返回
     {
        "msg": "添加成功",
        "result": [
            {
                "id": 128,
                "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413578576-f121d135f39f03e48da5fe5e8ced5b0a.jpg"
            },
            {
                "id": 129,
                "path": "http://shops-1251395798.cos.ap-nanjing.myqcloud.com/1600413580121-0d6fd1ff1f18dd1af4e296929a251cc4.jpg"
            }
        ]
    }
     *
     * @apiErrorExample 错误返回
     * {
     *  "msg":"请选择文件"
     * }
     *
     */
  // 多文件上传
  async multiple() {
    const { ctx, service } = this;
    const parts = ctx.multipart();
    let part;
    let type = '';
    // parts() 返回 promise 对象
    let cosData = null;
    const files = [];
    while ((part = await parts()) != null) {
      if (part.length) {
        // 这是 busboy 的字段
        type = part[1];
      } else {
        if (!part.filename) {
          // 这时是用户没有选择文件就点击了上传(part 是 file stream，但是 part.filename 为空)
          // 需要做出处理，例如给出错误提示消息
          return;
        }
        // part 是上传的文件流
        // console.log('field: ' + part.fieldname);
        // console.log('filename: ' + part.filename);
        // console.log('encoding: ' + part.encoding);
        // console.log('mime: ' + part.mime);
        // 文件处理，上传到云存储等等
        try {
          const filename =
            new Date().getTime() +
            '-' +
            crypto.createHash('md5').update(part.filename).digest('hex') +
            path.extname(part.filename);
          // eslint-disable-next-line no-loop-func
          cosData = await new Promise((resolve, reject) => {
            cos.putObject(
              {
                Bucket: 'shops-1251395798' /* Bucket,名称 必须 */,
                Region: 'ap-nanjing' /* 所属地域 必须 */,
                Key: filename /* 必须 */,
                Body: part, // 上传文件对象
                // eslint-disable-next-line no-loop-func
              },
              function (err, data) {
                // console.log('上传结束 =>', err || data);
                if (data) {
                  resolve('http://' + data.Location);
                } else {
                  reject(err);
                }
              }
            );
          });

          files.push(cosData);
        } catch (err) {
          // 必须将上传的文件流消费掉，要不然浏览器响应会卡死
          await sendToWormhole(part);
          throw err;
        }
      }
    }

    // 保存到数据库 返回上传的信息
    // console.log('files ==>', files);

    ctx.body = await service.shop.photo.index(files, type);
  }
}

module.exports = updateController;
